#pragma once
#include "Dx11Req.h"
#include "RendererBase.h"
#include <vector>
#define uint unsigned int
namespace NBGUI
{

	class GUIAPI Dx11Renderer: public RendererBase
	{
	public:
		void InitDx11(unsigned int width,
			unsigned int height,
			unsigned int freshRate,
			HWND window,
			bool fullscreen);

		void InitDx11(unsigned int width,
			unsigned int height,
			unsigned int freshRate,
			HWND window,
			bool fullscreen,
			ID3D11Device* device,
			ID3D11DeviceContext* context); // pasing device into init

		Dx11Renderer( HWND hWnd, unsigned int width, unsigned int height);
		//by device
		Dx11Renderer(HWND hWnd, ID3D11Device* device,ID3D11DeviceContext* context, unsigned int width, unsigned int height );
		virtual ~Dx11Renderer();


		//renderer side func
		void InitTexture();
		int createTexture(const char* path);
		int createTexture(const wchar_t* name, void* data, unsigned int width, unsigned int height, 
			unsigned int format, unsigned int type, int colorLen);
		ID3D11Texture2D* _createDX11Tex2D(void* data, uint width, uint height, uint format, uint type, int colorLen);
		ID3D11ShaderResourceView* _createShaderResourceView(ID3D11Texture2D* tex);

		int createVBO(void* buff, unsigned int length, unsigned int verSize ,unsigned int shIdx, char* fmt );
		int createIBO(void* pIBO, unsigned int length);
		bool updateVBO(void* newBuff, unsigned int start,unsigned int length,unsigned int verSize, int vboId );
		void deleteVBO(int vboId);
		void deleteIBO(int iboId);
		void swapBuffer(bool sync);
		void buildCamMatrix();

		//drawing
		void turnOffDepth();
		void beforeFrame();

		void initDrawing(void* vbuff, unsigned int vLength, void* ibuff, unsigned int iLength);
		void loadTex(Texture* tex);
		void drawIndexed( unsigned int startIdx, unsigned int len, int vboId, int iboId);
		void applyShader(unsigned int idx);
		void applyTexture(unsigned int idx);

		void _applyLastShaderResource();//inner function for shader resource
		
		
		
		
		
		
		int runMainLoop();
		void update();
		ID3DX11Effect* setupShaders(LPCTSTR fxName);



		inline HWND getHwnd(){return m_hWnd;}


	private:
		//dx11 
		ID3D11Device* m_device;
		ID3D11DeviceContext* m_context;
		IDXGISwapChain* m_swapChain;
		ID3D11RenderTargetView* m_rtview;
		ID3D11DepthStencilView* m_dsview;
		ID3D11RasterizerState* m_rs;		
		std::vector<ID3D11InputLayout*> m_inputLayoutVec;

		std::vector<ID3DX11Effect*> m_effectVec;//shaders
		
		std::vector<ID3D11Buffer*> m_vboVec;
		std::vector<ID3D11Buffer*> m_iboVec;

		//store the last "applyShader idx"
		int m_lastShaderIdx;

		ID3D11DepthStencilState* depthStencilState;//for depth

	private:
		//window
		HACCEL m_hAccelTable;
		HWND m_hWnd;


	private:
		std::vector<Texture*> texList;

	private:

		D3DXMATRIX m_projectionMatrix;
		D3DXMATRIX m_worldMatrix;
		D3DXMATRIX m_orthoMatrix;

		D3DXMATRIX m_viewMatrix;


	};
}